From 719eafa60c54d5e6512289d0e44fb6e47c023feb Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 12 Sep 2021 05:04:32 +0200 Subject: [PATCH] gl: Implement uploading and downloading HDR formats Also refactor the GL uploading so it does the fallback in a GLES-compatible way, which means we only need one fallback. --- gdk/gdkglcontext.c | 123 +++++++++++++++++++++++++-------------------- gdk/gdkgltexture.c | 36 +++++++++++++ 2 files changed, 104 insertions(+), 55 deletions(-) diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index 3357562add..76be3c7ef9 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -229,71 +229,84 @@ gdk_gl_context_upload_texture (GdkGLContext *context, { GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context); guchar *copy = NULL; - guint gl_internalformat; - guint gl_format; - guint gl_type; - guint bpp; + GLint gl_internalformat; + GLint gl_format; + GLint gl_type; + gsize bpp; g_return_if_fail (GDK_IS_GL_CONTEXT (context)); - if (priv->use_es) + if (!priv->use_es && data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */ { - /* GLES only supports rgba, so convert if necessary */ - if (data_format != GDK_MEMORY_R8G8B8A8_PREMULTIPLIED) - { - copy = g_malloc (width * height * 4); - gdk_memory_convert (copy, width * 4, - GDK_MEMORY_CONVERT_GLES_RGBA, - data, stride, data_format, - width, height); - stride = width * 4; - data = copy; - } - - bpp = 4; gl_internalformat = GL_RGBA8; - gl_format = GL_RGBA; + gl_format = GL_BGRA; + gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + else if (data_format == GDK_MEMORY_R8G8B8) /* Pixmap non-alpha data */ + { + gl_internalformat = GL_RGBA8; + gl_format = GL_RGB; gl_type = GL_UNSIGNED_BYTE; } - else + else if (priv->use_es && data_format == GDK_MEMORY_B8G8R8) { - if (data_format == GDK_MEMORY_DEFAULT) /* Cairo surface format */ - { - gl_internalformat = GL_RGBA8; - gl_format = GL_BGRA; - gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; - bpp = 4; - } - else if (data_format == GDK_MEMORY_R8G8B8) /* Pixmap non-alpha data */ - { - gl_internalformat = GL_RGBA8; - gl_format = GL_RGB; - gl_type = GL_UNSIGNED_BYTE; - bpp = 3; - } - else if (data_format == GDK_MEMORY_B8G8R8) - { - gl_internalformat = GL_RGBA8; - gl_format = GL_BGR; - gl_type = GL_UNSIGNED_BYTE; - bpp = 3; - } - else /* Fall-back, convert to cairo-surface-format */ - { - copy = g_malloc (width * height * 4); - gdk_memory_convert (copy, width * 4, - GDK_MEMORY_CONVERT_DOWNLOAD, - data, stride, data_format, - width, height); - stride = width * 4; - bpp = 4; - data = copy; - gl_internalformat = GL_RGBA8; - gl_format = GL_BGRA; - gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } + gl_internalformat = GL_RGBA8; + gl_format = GL_BGR; + gl_type = GL_UNSIGNED_BYTE; + } + else if (data_format == GDK_MEMORY_R16G16B16) + { + gl_internalformat = GL_RGBA16; + gl_format = GL_RGB; + gl_type = GL_UNSIGNED_SHORT; + } + else if (data_format == GDK_MEMORY_R16G16B16A16_PREMULTIPLIED) + { + gl_internalformat = GL_RGBA16; + gl_format = GL_RGBA; + gl_type = GL_UNSIGNED_SHORT; + } + else if (data_format == GDK_MEMORY_R16G16B16_FLOAT) + { + gl_internalformat = GL_RGB16F; + gl_format = GL_RGB; + gl_type = GL_HALF_FLOAT; + } + else if (data_format == GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED) + { + gl_internalformat = GL_RGBA16F; + gl_format = GL_RGBA; + gl_type = GL_HALF_FLOAT; + } + else if (data_format == GDK_MEMORY_R32G32B32_FLOAT) + { + gl_internalformat = GL_RGB32F; + gl_format = GL_RGB; + gl_type = GL_FLOAT; + } + else if (data_format == GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED) + { + gl_internalformat = GL_RGBA32F; + gl_format = GL_RGBA; + gl_type = GL_FLOAT; + } + else /* Fall-back, convert to GLES format */ + { + copy = g_malloc (width * height * 4); + gdk_memory_convert (copy, width * 4, + GDK_MEMORY_CONVERT_GLES_RGBA, + data, stride, data_format, + width, height); + data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; + stride = width * 4; + data = copy; + gl_internalformat = GL_RGBA8; + gl_format = GL_RGBA; + gl_type = GL_UNSIGNED_BYTE; } + bpp = gdk_memory_format_bytes_per_pixel (data_format); + /* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if * the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available */ diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c index 365a3a6ac2..6c91c70f70 100644 --- a/gdk/gdkgltexture.c +++ b/gdk/gdkgltexture.c @@ -105,6 +105,42 @@ gdk_gl_texture_download_texture (GdkTexture *texture) gl_type = GL_UNSIGNED_BYTE; break; + case GL_RGB16: + format = GDK_MEMORY_R16G16B16; + gl_format = GL_RGB; + gl_type = GL_UNSIGNED_SHORT; + break; + + case GL_RGBA16: + format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED; + gl_format = GL_RGBA; + gl_type = GL_UNSIGNED_SHORT; + break; + + case GL_RGB16F: + format = GDK_MEMORY_R16G16B16_FLOAT; + gl_format = GL_RGB; + gl_type = GL_HALF_FLOAT; + break; + + case GL_RGBA16F: + format = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED; + gl_format = GL_RGBA; + gl_type = GL_HALF_FLOAT; + break; + + case GL_RGB32F: + format = GDK_MEMORY_R32G32B32_FLOAT; + gl_format = GL_RGB; + gl_type = GL_FLOAT; + break; + + case GL_RGBA32F: + format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED; + gl_format = GL_RGBA; + gl_type = GL_FLOAT; + break; + default: g_warning ("Texture in unexpected format 0x%X (%d). File a bug about adding it to GTK", internal_format, internal_format); /* fallback to the dumbest possible format -- 2.30.2